<template>
    <div class="import-box">
      <pub-dialog
        v-if="importDialog"
        :title="props.dialogTitle"
        v-model:visible="importDialog"
        width="1000px"
      >
        <el-upload
          ref="uploadRef"
          drag
          action="#"
          :multiple="multiple"
          :accept="accept"
          :show-file-list="false"
          :limit="limit"
          :on-success="importFileSuccess"
          :http-request="uploadRequest"
          :before-upload="beforeUpload"
          :on-error="onError"
          :key="keyValue"
          :on-exceed="handleExceed"
          style="padding: 15px"
        >
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text">
            拖拽文件到这里或
            <em>点击上传</em>
            <div style="margin-top: 5px">文件格式：xls、xlsx</div>
          </div>
          <template #tip>
            <el-progress
              v-if="isShowProgress"
              style="margin: 15px auto 15px auto"
              :percentage="progressPercent"
              :text-inside="true"
              :stroke-width="15"
              :status="status"
            ></el-progress>
            <div class="upload-result" v-if="uploadOver">
              本次导入数据总计{{ total }}条，导入成功{{ successTotal }}条数据
              ，失败
              <span style="color: red">{{ errorTotal }}</span>
              条数据
              <span
                style="display: flex; align-items: center"
                v-if="errorTotal > 0"
              >
                ，
                <pub-download
                  :url="props.importErrorDownloadUrl"
                  fileType="excel"
                  :params="{ uuid: userStore.userInfo.id }"
                  file-name="失败数据"
                >
                  <template v-slot:default="slotProps">
                    <el-link
                      style="padding: 0 4px"
                      type="primary"
                      target="_blank"
                    >
                      <span
                        v-if="slotProps.loading"
                        style="
                          font-size: 13px;
                          display: inline-block;
                          width: 55px;
                        "
                      >
                        {{ loadingText }}
                      </span>
                      <span v-else style="font-size: 13px">点击下载失败数据</span>
                    </el-link>
                  </template>
                </pub-download>
                ，查看失败原因。
              </span>
            </div>
            <ul class="el-upload__tip">
              <li>
                <div style="display: flex; align-items: center">
                  <span>请上传一个Excel文件，文件格式必须符合模板格式。</span>
                  <pub-download
                    :url="templateDownloadUrl"
                    fileType="excel"
                    :params="{}"
                    :file-name="templateName"
                  >
                    <template v-slot:default="slotProps">
                      <el-link type="primary" target="_blank">
                        <span v-if="slotProps.loading">
                          {{ loadingText }}
                        </span>
                        <span v-else>点击下载模板</span>
                      </el-link>
                    </template>
                  </pub-download>
                </div>
              </li>
              <li>支持单次最大导入最多1万条数据。</li>
              <li v-if="!props.canRepeat">证件编号重复的数据，导入过程系统将自动过滤排除，禁止导入。</li>
              <li>
                导入过程中，符合系统校验的数据将成功入库；不符合条件的数据，将自动排除禁止入库并告知原因。
              </li>
            </ul>
          </template>
        </el-upload>
      </pub-dialog>
      <el-button
        :icon="Upload"
        class="btn-text-export"
        type="primary"
        @click="openDialog"
      >
        {{ props.btnName }}
      </el-button>
    </div>
  </template>
  
  <script setup>
  import { useUserStore } from '@/pinia/modules/user'
  import { fetchEventSource } from '@microsoft/fetch-event-source'
  import {
    watch,
    computed,
    ref,
    onMounted,
    onBeforeMount,
    onBeforeUnmount
  } from 'vue'
  import { ElMessage, genFileId } from 'element-plus'
  import { Upload } from '@element-plus/icons-vue'
  import axios from 'axios'
  
  const uploadOver = ref(false)
  const progressPercent = ref(0)
  const errorTotal = ref()
  const successTotal = ref()
  const total = ref()
  const importDialog = ref(false)
  const userStore = useUserStore()
  const props = defineProps({
    // 是否能导入重复数据，目前只控制弹框里的文字显示
    canRepeat:{
      type:Boolean,
      default:false
    },
    btnName: {
      type: String,
      default() {
        return '导入'
      }
    },
    dialogTitle: {
      type: String,
      default() {
        return '导入人员信息'
      }
    },
    importUrl: {
      type: String,
      default: '/biz/careWorker/import' //默认导入养老护理员
    },
    templateDownloadUrl: {
      type: String,
      default() {
        return 'ylhlyTemplate' //默认 养老护理员导入模板
      }
    },
    importErrorDownloadUrl: {
      type: String,
      default() {
        return 'hlyImportErrorUrl' //默认 养老护理员导入错误信息
      }
    },
    templateName: {
      type: String,
      default() {
        return '导入模板'
      }
    },
    disabled: {
      type: Boolean,
      default: false
    },
    multiple: {
      type: Boolean,
      default: false
    },
    accept: {
      type: String,
      default() {
        return ''
      }
    },
    limit: {
      type: Number,
      default: 1
    }
  })
  const status = ref('')
  const keyValue = ref(new Date().getTime())
  const isShowProgress = ref(false)
  const emit = defineEmits(['success', 'uploadSuccess'])
  const uploadRef = ref(null)
  
  const sseRequest = ref(null)
  
  const beforeUpload = () => {
    status.value = ''
    isShowProgress.value = true
  }
  const loadingText = ref('下载中...')
  const timer = ref(null)
  const startLoadingAnimation = () => {
    const dots = ['.', '..', '...']
    let dotIndex = 0
    if (!timer.value) {
      timer.value = setInterval(() => {
        dotIndex = (dotIndex + 1) % dots.length
        loadingText.value = '下载中' + dots[dotIndex]
      }, 500)
    }
  }
  startLoadingAnimation()
  const openDialog = () => {
    progressPercent.value = 0
    importDialog.value = true
  }
  
  const uploadRequest = param => {
    status.value = ''
    progressPercent.value = 0
    const formData = new FormData()
    formData.append('file', param.file)
    formData.append('uuid', userStore.userInfo.id)
    let baseApi =
      process.env.NODE_ENV == 'mm'
        ? '/gdmzylfw' + import.meta.env.VITE_BASE_API
        : import.meta.env.VITE_BASE_API
    const controller = new AbortController()
    const signal = controller.signal
    fetchEventSource(baseApi + props.importUrl, {
      method: 'POST',
      signal: signal,
      headers: {
        // 'Content-Type': 'application/json',
        Authorization: userStore.token
      },
      body: formData,
      onmessage(msg) {
        console.log('msg', msg)
        if (msg.event === '') {
          var result = JSON.parse(msg.data)
          console.log('result', result)
          // type 1进度 2异常 3成功
          if (result.type == 1) {
            progressPercent.value = result.value
          } else if (result.type == 2) {
            status.value = 'error'
            uploadOver.value = false
            ElMessage.error({
              dangerouslyUseHTMLString: true,
              message: result.value
            })
          } else if (result.type == 3) {
            status.value = 'success'
            progressPercent.value = 100
            successTotal.value = result.value.success
            errorTotal.value = result.value.fail
            total.value = result.value.total
            uploadOver.value = true
            emit('uploadSuccess')
          }
        } else if (msg.event === 'close') {
          controller.abort()
        }
      },
      onerror(err) {
        console.log(err)
        uploadOver.value = false
        status.value = 'error'
        throw err //必须throw才能停止
      }
    })
  }
  
  const handleExceed = files => {
    console.log(uploadRef)
    uploadRef.value.clearFiles()
    const file = files[0]
    file.uid = genFileId()
    uploadRef.value.handleStart(file)
    uploadRef.value.submit()
  }
  const importFileSuccess = res => {
    console.log(res)
    if (res.succeed) {
      ElMessage.success('导入成功')
      emit('success')
    } else {
      ElMessage.error({
        dangerouslyUseHTMLString: true,
        message: res.msg
      })
      keyValue.value = new Date().getTime()
    }
  }
  
  const onError = () => {
    ElMessage.error({
      dangerouslyUseHTMLString: true,
      message: res.msg || '系统异常'
    })
    status.value = 'error'
    progressPercent.value = 0
  }
  
  onBeforeUnmount(() => {
    if (timer.value) {
      timer.value = null
    }
  })
  </script>
  
  <style scoped lang="scss">
  .el-upload__tip {
    margin: 15px 15px 0 15px;
    font-size: 14px;
    li {
      list-style: disc;
      list-style-type: disc;
      margin-bottom: 5px;
    }
  }
  .upload-result {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    font-size: 13px;
    color: #67c23a;
  }
  </style>
  